#ifndef __KERNEL_DEF_H__
#define __KERNEL_DEF_H__

#if !defined(__CC_ARM) && !defined(__CLANG_ARM)
#include <sys/cdefs.h>
#define __weak __weak_symbol
#endif

#define container_of(ptr, type, member) \
    ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))

#define BIT(n) (1 << n)

typedef void (*init_fn_t)(void);

#define INIT_EXPORT(fn, level)                                                       \
	__attribute__((used)) const init_fn_t __init_##fn __attribute__((section(".init_fn." level))) = fn

#define INIT_BOARD_EXPORT(fn)   INIT_EXPORT(fn, "1")
#define INIT_DEVICE_EXPORT(fn)  INIT_EXPORT(fn, "2")
#define INIT_APP_EXPORT(fn)     INIT_EXPORT(fn, "3")

#ifdef USE_ASSERT
	extern void assert_failed(char *file_name, int line);
	#define assert(expr)   ((expr) ? (void)0 : assert_failed(__FILE__, __LINE__))
#else
	#define assert(expr)   (void)0
#endif

#define LOG_LEVEL_ERROR   0
#define LOG_LEVEL_WARNING 1
#define LOG_LEVEL_DEBUG   2
#define LOG_LEVEL_INFO    3

#ifdef USE_DEBUG
extern void print_log(int level, const char *buffer, ...);
#define log(level, buf, ...)  print_log(level, buf "\r\n", ##__VA_ARGS__)
#else
#define log(level, buf, ...)
#endif

#if (LOG_LEVEL >= LOG_LEVEL_ERROR)
#define log_e(buf, ...)  log(LOG_LEVEL_ERROR, "[E]: " buf, ##__VA_ARGS__)
#else
#define log_e(buf, ...)
#endif
#if (LOG_LEVEL >= LOG_LEVEL_WARNING)
#define log_w(buf, ...)  log(LOG_LEVEL_WARNING, "[W]: " buf, ##__VA_ARGS__)
#else
#define log_w(buf, ...)
#endif
#if (LOG_LEVEL >= LOG_LEVEL_DEBUG)
#define log_d(buf, ...)  log(LOG_LEVEL_DEBUG, "[D]: " buf, ##__VA_ARGS__)
#else
#define log_d(buf, ...)
#endif
#if (LOG_LEVEL >= LOG_LEVEL_INFO)
#define log_i(buf, ...)  log(LOG_LEVEL_INFO, "[I]: " buf, ##__VA_ARGS__)
#else
#define log_i(buf, ...)
#endif

#define __align(size, align)       (((size) + (align) - 1) & ~((align) - 1))
#define __align_down(size, align)  ((size) & ~((align) - 1))

#define EIO      1 // IO错误
#define ENXIO    2 // 没有这样的设备或地址
#define E2BIG    3 // 参数太长
#define EAGAIN   4 // Try again
#define ENOMEM   5 // 内存不足
#define EFAULT   6 // 错误的地址
#define EBUSY    7 // 设备或资源忙
#define ENODEV   8 // 没有这样的设备
#define EINVAL   9 // 非法参数
#define ENOSPC   10 // 设备空间不足
#define ESPIPE   11 // Illegal seek
#define EROFS    12 // 只读文件系统
#define EDOM     13 // Math argument out of domain of func
#define ERANGE   14 // 数学结果无法表示
#define ENAMETOOLONG 15 // 文件名字太长

#endif /* __KERNEL_DEF_H__ */
